package com.gitee.wsl.mathematics.geometry.d2.rect.ext

import com.gitee.wsl.mathematics.coordinate.d2.Coordinate2
import com.gitee.wsl.mathematics.geometry.d2.rect.RectangleShape2d
import com.gitee.wsl.mathematics.vector.ext.clamp
import com.gitee.wsl.mathematics.vector.vec2.Vector2


/**
 * Clamps a [Vector2] within the bounds of the [bounds] `Rectangle`.
 */
fun<N:Number,V:Coordinate2<N, V>> V.clamp(bounds: RectangleShape2d<N,V,*>) =
    this.clamp(bounds.corner, bounds.corner + bounds.dimensions)

/**
 * Remaps [Vector2] from a position on the [sourceRectangle] to
 * a proportionally equivalent position on the [targetRectangle].
 *
 * @param clamp Clamps remapped value within the bounds of [targetRectangle].
 */
fun<N:Number,V:Coordinate2<N, V>> V.map(sourceRectangle: RectangleShape2d<N,V,*>, targetRectangle: RectangleShape2d<N,V,*>, clamp: Boolean = false):V {
    val remapped =
        (this - sourceRectangle.corner) / sourceRectangle.dimensions * targetRectangle.dimensions + targetRectangle.corner
    return if (clamp) remapped.clamp(targetRectangle) else remapped
}

/**
 * Maps all elements in a `List<Vector2>`
 * from [sourceRectangle] to [targetRectangle].
 * If [clamp] is true all elements are clamped within the bounds of [targetRectangle].
 */
fun<N:Number,V:Coordinate2<N, V>> List<V>.map(sourceRectangle: RectangleShape2d<N,V,*>, targetRectangle: RectangleShape2d<N,V,*>, clamp: Boolean = false)=
    this.map { it.map(sourceRectangle, targetRectangle, clamp) }



fun<N:Number,V:Coordinate2<N, V>> V.map(rect: RectangleShape2d<N,V,*>): V {
    val nx = (x - rect.x) / rect.width
    val ny = (y - rect.y) / rect.height
    return create(nx, ny)
}